/**
 * 图谱渲染器扩展
 * 提供更多专业图谱类型的渲染函数
 */
import * as d3 from 'd3';
import { getGraphTypeStyle, getNodeShapeRenderer } from '../styles/graphThemes';
import { calculateNodeDegrees, createDragBehavior } from './graphLayoutUtils.jsx';

/**
 * 概念图谱专用渲染
 */
export const renderConceptMap = (container, nodes, edges, width, height, onNodeClick, editable, onNodePositionUpdate) => {
  // 获取概念图谱样式
  const conceptStyle = getGraphTypeStyle('concept');
  
  // 概念图谱使用层次布局，但有特殊的视觉样式
  const simulation = d3.forceSimulation(nodes)
    .force('link', d3.forceLink(edges).id(d => d.id).distance(150))
    .force('charge', d3.forceManyBody().strength(-600))
    .force('center', d3.forceCenter(width / 2, height / 2))
    .force('collision', d3.forceCollide().radius(50))
    .force('x', d3.forceX(width / 2).strength(0.05))
    .force('y', d3.forceY(height / 2).strength(0.05));
  
  // 初始化节点位置，避免堆叠
  nodes.forEach((node, i) => {
    if (!node.x || !node.y) {
      const angle = (i / nodes.length) * 2 * Math.PI;
      const radius = Math.min(width, height) * 0.3;
      node.x = width / 2 + radius * Math.cos(angle);
      node.y = height / 2 + radius * Math.sin(angle);
    }
  });

  // 创建连接线 - 概念图谱样式
  const links = container.append('g')
    .attr('class', 'concept-links')
    .selectAll('line')
    .data(edges.filter(edge => {
      // 确保源节点和目标节点都存在
      const sourceExists = nodes.some(node => node.id === edge.source);
      const targetExists = nodes.some(node => node.id === edge.target);
      return sourceExists && targetExists;
    }))
    .enter().append('line')
    .attr('stroke', d => conceptStyle.edgeColor(d))
    .attr('stroke-width', d => conceptStyle.edgeWidth(d))
    .attr('opacity', 0.7);

  // 创建关系标签背景
  const linkLabels = container.append('g')
    .attr('class', 'concept-link-labels')
    .selectAll('g')
    .data(edges.filter(e => e.label))
    .enter().append('g');

  linkLabels.append('rect')
    .attr('fill', '#fff')
    .attr('stroke', d => conceptStyle.edgeColor(d))
    .attr('stroke-width', 1)
    .attr('rx', 8);

  linkLabels.append('text')
    .text(d => d.label)
    .attr('text-anchor', 'middle')
    .attr('dy', '0.35em')
    .attr('font-size', typeof conceptStyle.labelSize === 'function' ? d => conceptStyle.labelSize(d) : conceptStyle.labelSize)
    .attr('fill', d => conceptStyle.edgeColor(d));

  // 创建节点 - 概念图谱样式
  const nodeGroups = container.append('g')
    .attr('class', 'concept-nodes')
    .selectAll('g')
    .data(nodes)
    .enter().append('g')
    .style('cursor', 'pointer')
    .call(createDragBehavior(simulation, editable, onNodePositionUpdate))
    .on('click', (event, d) => {
      event.stopPropagation();
      onNodeClick?.(d);
    });

  // 使用节点形状渲染器
  const nodeShape = conceptStyle.nodeShape || 'hexagon';
  const shapeRenderer = getNodeShapeRenderer(nodeShape, d3, container);
  
  nodeGroups.each(function(d) {
    const group = d3.select(this);
    
    // 渲染节点形状
    shapeRenderer(group.datum(d => ({
      ...d,
      color: conceptStyle.nodeColor(d),
      size: conceptStyle.nodeSize(d)
    })));

    // 添加文本
    group.append('text')
      .text(d.label)
      .attr('text-anchor', 'middle')
      .attr('dy', '0.35em')
      .attr('fill', conceptStyle.labelColor)
      .attr('font-size', typeof conceptStyle.labelSize === 'function' ? conceptStyle.labelSize(d) : conceptStyle.labelSize)
      .attr('font-weight', 'bold');
  });

  // 更新位置
  simulation.on('tick', () => {
    links
      .attr('x1', d => d.source.x)
      .attr('y1', d => d.source.y)
      .attr('x2', d => d.target.x)
      .attr('y2', d => d.target.y);

    nodeGroups.attr('transform', d => `translate(${d.x},${d.y})`);

    linkLabels.attr('transform', d => {
      const x = (d.source.x + d.target.x) / 2;
      const y = (d.source.y + d.target.y) / 2;
      return `translate(${x},${y})`;
    });

    // 更新标签背景大小
    linkLabels.select('rect')
      .attr('x', function() {
        const textWidth = this.nextSibling.getBBox().width;
        return -textWidth/2 - 4;
      })
      .attr('y', -8)
      .attr('width', function() {
        const textWidth = this.nextSibling.getBBox().width;
        return textWidth + 8;
      })
      .attr('height', 16);
  });

  return simulation;
};

/**
 * 流程图谱专用渲染
 */
export const renderFlowChart = (container, nodes, edges, width, height, onNodeClick) => {
  // 获取流程图谱样式
  const flowStyle = getGraphTypeStyle('flow');
  
  // 流程图使用有向图布局
  const layoutedNodes = [...nodes];
  
  // 简单的流程图布局算法
  const levels = new Map();
  const visited = new Set();
  
  // 找到起始节点
  const startNodes = nodes.filter(node => 
    !edges.some(edge => edge.target === node.id)
  );
  
  if (startNodes.length === 0) {
    startNodes.push(nodes[0]);
  }

  // BFS分层
  const queue = startNodes.map(node => ({ node, level: 0 }));
  startNodes.forEach(node => {
    levels.set(node.id, 0);
    visited.add(node.id);
  });

  while (queue.length > 0) {
    const { node, level } = queue.shift();
    
    edges.forEach(edge => {
      if (edge.source === node.id && !visited.has(edge.target)) {
        const targetNode = nodes.find(n => n.id === edge.target);
        if (targetNode) {
          levels.set(edge.target, level + 1);
          visited.add(edge.target);
          queue.push({ node: targetNode, level: level + 1 });
        }
      }
    });
  }

  // 按层级分组
  const levelGroups = new Map();
  levels.forEach((level, nodeId) => {
    if (!levelGroups.has(level)) levelGroups.set(level, []);
    levelGroups.get(level).push(nodeId);
  });

  // 计算位置
  const levelHeight = height / (levelGroups.size + 1);
  layoutedNodes.forEach(node => {
    const level = levels.get(node.id) || 0;
    const levelNodes = levelGroups.get(level) || [];
    const index = levelNodes.indexOf(node.id);
    const levelWidth = width / (levelNodes.length + 1);
    
    node.x = (index + 1) * levelWidth;
    node.y = (level + 1) * levelHeight;
    node.fx = node.x;
    node.fy = node.y;
  });

  // 创建箭头标记
  const defs = container.append('defs');
  defs.append('marker')
    .attr('id', 'arrowhead')
    .attr('viewBox', '0 -5 10 10')
    .attr('refX', 8)
    .attr('refY', 0)
    .attr('markerWidth', 6)
    .attr('markerHeight', 6)
    .attr('orient', 'auto')
    .append('path')
    .attr('d', 'M0,-5L10,0L0,5')
    .attr('fill', '#666');

  // 创建连接线 - 流程图样式
  const links = container.append('g')
    .attr('class', 'flow-links')
    .selectAll('line')
    .data(edges.filter(edge => {
      // 确保源节点和目标节点都存在于layoutedNodes中
      const sourceExists = layoutedNodes.some(node => node.id === edge.source);
      const targetExists = layoutedNodes.some(node => node.id === edge.target);
      return sourceExists && targetExists;
    }))
    .enter().append('line')
    .attr('x1', d => {
      const source = layoutedNodes.find(n => n.id === d.source);
      return source ? source.x : 0;
    })
    .attr('y1', d => {
      const source = layoutedNodes.find(n => n.id === d.source);
      return source ? source.y : 0;
    })
    .attr('x2', d => {
      const target = layoutedNodes.find(n => n.id === d.target);
      return target ? target.x : 0;
    })
    .attr('y2', d => {
      const target = layoutedNodes.find(n => n.id === d.target);
      return target ? target.y : 0;
    })
    .attr('stroke', d => flowStyle.edgeColor(d))
    .attr('stroke-width', d => flowStyle.edgeWidth(d))
    .attr('marker-end', 'url(#arrowhead)');

  // 创建节点 - 流程图样式
  const nodeGroups = container.append('g')
    .attr('class', 'flow-nodes')
    .selectAll('g')
    .data(layoutedNodes)
    .enter().append('g')
    .attr('transform', d => `translate(${d.x},${d.y})`)
    .style('cursor', 'pointer')
    .on('click', (event, d) => {
      event.stopPropagation();
      onNodeClick?.(d);
    });

  // 根据节点类型绘制不同形状
  nodeGroups.each(function(d) {
    const group = d3.select(this);
    const nodeType = d.type || 'process';
    
    // 根据节点类型选择形状
    let nodeShape;
    switch (nodeType) {
      case 'start':
      case 'end':
        nodeShape = 'ellipse';
        break;
      case 'decision':
        nodeShape = 'diamond';
        break;
      default:
        nodeShape = 'rect';
    }
    
    // 使用节点形状渲染器
    const shapeRenderer = getNodeShapeRenderer(nodeShape, d3, container);
    shapeRenderer(group.datum(d => ({
      ...d,
      color: flowStyle.nodeColor(d),
      size: flowStyle.nodeSize(d)
    })));

    // 添加文本
    group.append('text')
      .text(d.label)
      .attr('text-anchor', 'middle')
      .attr('dy', '0.35em')
      .attr('fill', flowStyle.labelColor)
      .attr('font-size', typeof flowStyle.labelSize === 'function' ? flowStyle.labelSize(d) : flowStyle.labelSize)
      .attr('font-weight', 'bold');
  });

  return layoutedNodes;
};

/**
 * 社交网络专用渲染
 */
export const renderSocialNetwork = (container, nodes, edges, width, height, onNodeClick, editable, onNodePositionUpdate) => {
  // 获取社交网络样式
  const socialStyle = getGraphTypeStyle('social');
  
  // 计算节点度数
  const nodeDegrees = calculateNodeDegrees(nodes, edges);

  // 社交网络力导向布局
  const simulation = d3.forceSimulation(nodes)
    .force('link', d3.forceLink(edges).id(d => d.id).distance(d => {
      // 根据关系类型调整距离
      const relationStrengths = {
        'friend': 100,
        'family': 80,
        'colleague': 120,
        'follow': 140
      };
      return relationStrengths[d.type] || 110;
    }))
    .force('charge', d3.forceManyBody().strength(d => {
      // 重要节点排斥力更强
      const degree = nodeDegrees.get(d.id) || 1;
      return -300 - degree * 30;
    }))
    .force('center', d3.forceCenter(width / 2, height / 2))
    .force('collision', d3.forceCollide().radius(d => {
      const degree = nodeDegrees.get(d.id) || 1;
      return socialStyle.nodeSize(d) + degree * 3;
    }))
    .force('x', d3.forceX(width / 2).strength(0.05))
    .force('y', d3.forceY(height / 2).strength(0.05));
    
  // 初始化节点位置，避免堆叠
  nodes.forEach((node, i) => {
    if (!node.x || !node.y) {
      const angle = (i / nodes.length) * 2 * Math.PI;
      const radius = Math.min(width, height) * 0.3;
      node.x = width / 2 + radius * Math.cos(angle);
      node.y = height / 2 + radius * Math.sin(angle);
    }
  });

  // 创建连接线 - 社交网络样式
  const links = container.append('g')
    .attr('class', 'social-links')
    .selectAll('line')
    .data(edges.filter(edge => {
      // 确保源节点和目标节点都存在
      const sourceExists = nodes.some(node => node.id === (typeof edge.source === 'object' ? edge.source.id : edge.source));
      const targetExists = nodes.some(node => node.id === (typeof edge.target === 'object' ? edge.target.id : edge.target));
      return sourceExists && targetExists;
    }))
    .enter().append('line')
    .attr('stroke', d => socialStyle.edgeColor(d))
    .attr('stroke-width', d => socialStyle.edgeWidth(d))
    .attr('opacity', 0.6);

  // 创建节点 - 社交网络样式
  const nodeGroups = container.append('g')
    .attr('class', 'social-nodes')
    .selectAll('g')
    .data(nodes)
    .enter().append('g')
    .style('cursor', 'pointer')
    .call(createDragBehavior(simulation, editable, onNodePositionUpdate))
    .on('click', (event, d) => {
      event.stopPropagation();
      onNodeClick?.(d);
    });

  // 根据重要性绘制不同大小的节点
  nodeGroups.each(function(d) {
    const group = d3.select(this);
    const degree = nodeDegrees.get(d.id) || 1;
    const radius = socialStyle.nodeSize(d);
    
    // 外圈 - 表示影响力
    group.append('circle')
      .attr('r', radius + 3)
      .attr('fill', 'none')
      .attr('stroke', socialStyle.nodeColor(d))
      .attr('stroke-width', 1)
      .attr('opacity', 0.3);
    
    // 主节点
    group.append('circle')
      .attr('r', radius)
      .attr('fill', socialStyle.nodeColor(d))
      .attr('stroke', '#fff')
      .attr('stroke-width', 2);

    // 添加头像或图标
    if (d.avatar) {
      group.append('image')
        .attr('href', d.avatar)
        .attr('x', -radius + 2)
        .attr('y', -radius + 2)
        .attr('width', (radius - 2) * 2)
        .attr('height', (radius - 2) * 2)
        .attr('clip-path', `circle(${radius - 2}px)`);
    }

    // 添加文本
    group.append('text')
      .text(d.label)
      .attr('text-anchor', 'middle')
      .attr('dy', radius + 15)
      .attr('fill', socialStyle.labelColor)
      .attr('font-size', typeof socialStyle.labelSize === 'function' ? socialStyle.labelSize(d) : socialStyle.labelSize);
  });

  // 更新位置
  simulation.on('tick', () => {
    links
      .attr('x1', d => d.source.x)
      .attr('y1', d => d.source.y)
      .attr('x2', d => d.target.x)
      .attr('y2', d => d.target.y);

    nodeGroups.attr('transform', d => `translate(${d.x},${d.y})`);
  });

  return simulation;
};

/**
 * 本体图谱专用渲染
 */
export const renderOntologyGraph = (container, nodes, edges, width, height, onNodeClick, editable, onNodePositionUpdate) => {
  // 获取本体图谱样式
  const ontologyStyle = getGraphTypeStyle('knowledge');
  
  // 本体图谱使用严格的层次结构
  const simulation = d3.forceSimulation(nodes)
    .force('link', d3.forceLink(edges).id(d => d.id).distance(120))
    .force('charge', d3.forceManyBody().strength(-400))
    .force('center', d3.forceCenter(width / 2, height / 2))
    .force('collision', d3.forceCollide().radius(40))
    .force('x', d3.forceX(width / 2).strength(0.05))
    .force('y', d3.forceY(d => {
      // 根据节点类型设置垂直位置
      const typePositions = {
        'class': 0.2,
        'property': 0.5,
        'individual': 0.8
      };
      return (typePositions[d.type] || 0.5) * height;
    }).strength(0.2));
    
  // 初始化节点位置，避免堆叠
  nodes.forEach((node, i) => {
    if (!node.x || !node.y) {
      const angle = (i / nodes.length) * 2 * Math.PI;
      const radius = Math.min(width, height) * 0.3;
      node.x = width / 2 + radius * Math.cos(angle);
      node.y = height / 2 + radius * Math.sin(angle);
    }
  });

  // 创建连接线 - 本体图谱样式
  const links = container.append('g')
    .attr('class', 'ontology-links')
    .selectAll('line')
    .data(edges.filter(edge => {
      // 确保源节点和目标节点都存在
      const sourceExists = nodes.some(node => node.id === (typeof edge.source === 'object' ? edge.source.id : edge.source));
      const targetExists = nodes.some(node => node.id === (typeof edge.target === 'object' ? edge.target.id : edge.target));
      return sourceExists && targetExists;
    }))
    .enter().append('line')
    .attr('stroke', d => {
      const relationColors = {
        'subClassOf': '#722ed1',
        'instanceOf': '#1677ff',
        'hasProperty': '#52c41a',
        'equivalentTo': '#fa8c16'
      };
      return relationColors[d.type] || ontologyStyle.edgeColor(d);
    })
    .attr('stroke-width', d => ontologyStyle.edgeWidth(d))
    .attr('stroke-dasharray', d => d.type === 'equivalentTo' ? '5,5' : 'none');

  // 创建节点 - 本体图谱样式
  const nodeGroups = container.append('g')
    .attr('class', 'ontology-nodes')
    .selectAll('g')
    .data(nodes)
    .enter().append('g')
    .style('cursor', 'pointer')
    .call(createDragBehavior(simulation, editable, onNodePositionUpdate))
    .on('click', (event, d) => {
      event.stopPropagation();
      onNodeClick?.(d);
    });

  // 根据本体类型绘制不同形状
  nodeGroups.each(function(d) {
    const group = d3.select(this);
    const nodeType = d.type || 'class';
    
    let nodeShape;
    switch (nodeType) {
      case 'class':
        nodeShape = 'rect';
        break;
      case 'property':
        nodeShape = 'ellipse';
        break;
      case 'individual':
        nodeShape = 'circle';
        break;
      default:
        nodeShape = 'circle';
    }
    
    // 使用节点形状渲染器
    const shapeRenderer = getNodeShapeRenderer(nodeShape, d3, container);
    shapeRenderer(group.datum(d => ({
      ...d,
      color: ontologyStyle.nodeColor(d),
      size: ontologyStyle.nodeSize(d)
    })));

    // 添加文本
    group.append('text')
      .text(d.label)
      .attr('text-anchor', 'middle')
      .attr('dy', '0.35em')
      .attr('fill', ontologyStyle.labelColor)
      .attr('font-size', typeof ontologyStyle.labelSize === 'function' ? ontologyStyle.labelSize(d) : ontologyStyle.labelSize)
      .attr('font-weight', 'bold');
  });

  // 更新位置
  simulation.on('tick', () => {
    links
      .attr('x1', d => d.source.x)
      .attr('y1', d => d.source.y)
      .attr('x2', d => d.target.x)
      .attr('y2', d => d.target.y);

    nodeGroups.attr('transform', d => `translate(${d.x},${d.y})`);
  });

  return simulation;
};
